JPA로 DB Create 수행하기
✒️ 2025-05-28 14:05 내용 수정
스프링부트3 자바 백엔드 개발입문 내용 참고 및 정리
- 이전에 Spring boot 수업에선 MyBatis를 사용하여 CRUD를 진행했다. 이번에는 참고서의 내용으로 JPA를 사용하여 H2 DB에 CRUD를 수행하는 실습을 진행했다.
- 템플릿 엔진도 Thymeleaf 대신 Mustache를 사용했다.
기본 설정 - 메인 페이지
- Spring boot에서 프로젝트 설정 및 빌드를 먼저 수행한다.
src/main/java/project_package패키지에controller패키지를 만들고,FirstController클래스를 생성한다.- 이 Controller는 메인 페이지를 관리할 Controller이다.
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller // controller임을 명시하는 Annotation
public class FirstController {
@GetMapping("/")
public String newToMustache(Model model) {
model.addAttribute("name", "Jake"); // name이라는 변수에 Jake를 할당
return "index"; // index.mustache 파일을 반환
}
}
- 메인 페이지가 될 파일을
mustache로 만들기 위해src/main/resources/templates폴더에index.mustache파일을 생성한다.!를 입력하고Tab을 누르면 기본 HTML 코드가 작성된다.- Bootstrap을 사용하여 일부 디자인을 꾸미기 위해
<script>와<link>가 적용되었다.
<!doctype html>
<!-- index.mustache -->
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<title>SpringBoot Example</title>
</head>
<body>
{{! layouts/header.mustache 사용하기 }}
{{> layouts/header }}
<section>
<div class="inner bg-dark text-white p-5">
<div class="container">
<div>
<h1>Hello, {{name}}!</h1>
</div>
</div>
</div>
</section>
{{! layouts/footer.mustache 사용하기 }}
{{> layouts/footer }}
</body>
</html>
- 여기서
header와footer는 다른mustache파일로 작성하여index.mustache에서 사용되었다.
{{! layouts/header.mustache }}
{{! bootstrap nav를 그대로 적용했다. }}
<header>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="/">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Articles</a>
</li>
<li class="nav-item">
<!-- Controller에서 mapping을 추가할 예정 -->
<a class="nav-link" href="/articles/new">Write Articles</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
{{! layouts/footer.mustache }}
<footer>
<div class="mb-5 container-fluid">
<hr>
<p>CloudStudying | <a href="#">Privacy</a> | <a href="#">Terms</a></p>
</div>
</footer>
- 기본 설정을 마치고
ProjectNameApplication을 실행한 후, 브라우저에http://localhost:port/를 입력하면index.mustache파일의 내용이 출력된다.
데이터 추가하기
- view로부터
form데이터를 전달받아 DB에 데이터를 전달하기 위한 객체인 DTO를 생성한다.src/main/java/package_name패키지에DTO패키지를 생성하고,ArticleForm이라는 클래스를 생성한다.
package com.example.demo.DTO;
import com.example.demo.entity.Article;
import lombok.Data;
@Data // Lombok - 생성자, getter, setter를 생성해준다
public class ArticleForm {
private String title;
private String content;
public Article toEntity() { // ArticleForm을 Entity인 Article로 변환할 메소드
return new Article(null, title, content);
}
}
form데이터를 받기 위한 페이지를 만들기 위해src/resources/templates/articles폴더를 생성하고,new.mustache파일을 생성한다.
<!doctype html>
<!-- new.mustache -->
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<title>SpringBoot Example</title>
</head>
<body>
{{> layouts/header }}
<section>
<div class="inner p-5">
<!-- Controller의 /articles/create mapping을 추가해 create 동작을 수행할 예정 -->
<form action="/articles/create" method="POST" class="container">
<div class="mb-3">
<label class="form-label">제목</label>
<input type="text" class="form-control" name="title">
</div>
<div class="mb-3">
<label class="form-label">내용</label>
<textarea class="form-control" name="content"></textarea>
</div>
<button type="submit">Submit</button>
</form>
</div>
</section>
{{> layouts/footer }}
</body>
</html>
- DB의 테이블과 매칭될
Article클래스를 만들기 위해src/main/java/package_name/에entity패키지를 생성하고,Article클래스를 만든다.- 이런 역할을 하는 객체를 JPA에서
Entity로 부른다.
- 이런 역할을 하는 객체를 JPA에서
package com.example.demo.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Data;
@Entity // Entity임을 명시하는 Annotation
@Data // Lombok
public class Article {
@Id // 식별자
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column // DB에서 열과 대응되는 속성
private String title;
@Column
private String content;
public Article(Long id, String title, String content) {
this.id = id;
this.title = title;
this.content = content;
}
}
src/main/java/package_name/패키지에repository패키지를 추가하고,Entity를 관리할Repository인터페이스를 생성한다.
package com.example.demo.repository;
import com.example.demo.entity.Article;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ArticleRepository extends CrudRepository<Article, Long> {
// 다른 메소드를 추가한다면 여기에 작성한다.
// 인터페이스이므로 추상 메소드만 가져야 하며, 실제 구현은 클래스가 구현해야 한다.
}
- 이제 articles과 관련된 동작을 처리하기 위한 Controller를 만든다.
src/main/java/package_name/에controller패키지가 없다면 생성하고, 존재한다면ArticleController를 생성한다.
package com.example.demo.controller;
import com.example.demo.DTO.ArticleForm;
import com.example.demo.entity.Article;
import com.example.demo.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // controller 임을 명시하는 Annotation
@RequestMapping("/articles") // Request의 path가 /articles로 시작하는 mapping을 공통으로 지정
public class ArticleController {
@Autowired // 의존성 주입 - Spring boot가 자동으로 객체를 주입함
private ArticleRepository articleRepository; // Entity를 관리할 Repository
@GetMapping("new") // url에 /articles/new로 요청 가능
public String newArticleForm() {
return "/articles/new"; // src/main/resources/templates/articles/new.mustache를 반환
}
@PostMapping("create") // url에 /articles/create로 요청 가능
public String createArticle(ArticleForm form) { // form data에서 들어온 값을 DTO에 저장
System.out.println(form.toString()); // 값 확인
Article article = form.toEntity(); // DTO를 Entity로 변환
System.out.println(article.toString());
Article saved = articleRepository.save(article); // Entity를 저장
System.out.println(saved.toString());
return "";
}
}
- 브라우저에
http://localhost:port/articles/new를 입력해 form 입력 페이지로 접속 후 제목과 내용을 입력한 뒤 버튼을 누른다.
- 현재
post동작의 return에는 지정된 값이 없어 에러가 뜨지만 IntelliJ의 터미널엔System.out.println()메소드의 내용을 확인할 수 있다.
H2 DB 설정하기
- H2 DB의 웹 콘솔에 접근하기 위해
application.properties파일 또는application.yml파일에 DB 접근 구문을 추가한다.
# .properties 파일
# 한글 깨짐 방지
server.servlet.encoding.force=true
# H2 console 접근
spring.h2.console.enabled=true
# .yml 파일
# server 설정
server:
port: 9000
servlet:
encoding:
force: true
# H2 console 접근
spring:
h2:
console:
enabled: true
- IntelliJ의 Run 탭에서
H2 console available at '/h2-console'. Database available at항목을 찾아jdbc부분을 복사한다.
- 브라우저에
http://localhost:9000/h2-console/을 입력하고, JDBC URL 부분에 방금 복사한 부분을 붙여넣은 후 Connect를 눌러 연결한다.
- H2 콘솔에서 왼쪽에 위에서 추가한 Article이라는
Entity가 테이블로 등록되어 있는 것을 확인할 수 있다. Article을 누르고 Run을 누르면 테이블의 데이터를 조회할 수 있다.- 현재는 서버를 재시작해서 데이터가 없다. 교재 설명에 따르면 H2 DB는 모든 입출력을 메모리 모드에서 돌리기에 서버를 재시작하면 DB에 저장된 내용이 사라진다고 한다.
- DB에 값이 저장되는지 확인하기 위해
http://localhost:9000/articles/new에서 새 값을 입력하고 추가한다. 그 후 H2 콘솔에서 Run 버튼을 다시 눌러 데이터가 추가되었는지 확인한다.